<?php

namespace Apps\Weixin\Controllers;


use Apps\Common\Constant\BusinessConstant;
use Apps\Common\Controller\BaseController;
use Apps\Weixin\Services\WxMessageService;
use Apps\Weixin\Services\WxRecordService;
use Apps\Weixin\Services\WxResourceService;
use Deyi\Functions\UtilFunction;
use Vendor\Weixin\WXBizMsgCrypt;

class EventController extends BaseController
{
    const VERIFY_APPID = 'wx570bc396a51b8ff8';

    private function getPostParamsAndDecryptMsg()
    {
        $data = $this->request->getRawBody();
        $nonceStr = $this->getParamValue('nonce');
        $timeStamp = $this->getParamValue('timestamp');
        $encryptType = $this->getParamValue('encrypt_type');
        $msgSign = $this->getParamValue('msg_signature');

        $wxMsg = new WXBizMsgCrypt(static::$_config->weixin->token, static::$_config->weixin->aeskey, static::$_config->weixin->appid);

        $ret = $wxMsg->decryptMsg($msgSign, $timeStamp, $nonceStr, $data, $message);

        if ($ret) {
            static::$_logger->error('event auth fail, code:' . $ret, ' msg:' . $message);
            return false;
        }
        static::$_config->project->debug ? static::$_logger->info('weixin notify xml:' . $message) : '';
        return json_decode(json_encode(simplexml_load_string($message, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS), JSON_UNESCAPED_UNICODE));
    }

    private function replyTextMessageByEncrypt($fromUserName, $toUserName, $content)
    {
        $msgTpl = <<<EOF
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>
EOF;
        $time = time();
        $nonce = md5(UtilFunction::getRandomString(128));
        $msg = sprintf($msgTpl, $toUserName, $fromUserName, $time, $content);

        static::$_logger->info('reply text: ' . $msg);

        $wxMsg = new WXBizMsgCrypt(static::$_config->weixin->token, static::$_config->weixin->aeskey, static::$_config->weixin->appid);
        if ($ret = $wxMsg->encryptMsg($msg, $time, $nonce, $encryptMsg)) {
            static::$_logger->error('encrypt weixin text msg fail:' . $ret);
        }
        return $encryptMsg;
    }

    public function authAction()
    {
        $xml = $this->getPostParamsAndDecryptMsg();

        if ($xml) {
            switch ($xml->InfoType) {
                case BusinessConstant::RECORD_SKEY_VERIFY_TICKET:
                    $this->setVerifyTicket($xml);
                    break;
                case '';

                    break;
                case '':

                    break;

                case '':
                    break;
            }
        }

        echo 'success';
    }

    public function notifyAction()
    {
        $appId = str_replace('/', '', $this->getParamValue('appid'));

        $xml = $this->getPostParamsAndDecryptMsg();

        if (!$xml) {
            static::$_logger->error('parse notify xml fail');
            return;
        }

        $content = $xml->Content;

        //微信官方测试号,全网发布使用
        if (($appId === self::VERIFY_APPID) && ($xml->ToUserName == 'gh_3c884a361561')) {
            $replyContent = '';
            if (isset($xml->Event)) {
                $replyContent = 'LOCATIONfrom_callback';
            } elseif ($content == 'TESTCOMPONENT_MSG_TYPE_TEXT') {
                $replyContent = 'TESTCOMPONENT_MSG_TYPE_TEXT_callback';
            } elseif (strpos($content, 'QUERY_AUTH_CODE:') !== false) {
                $replyContent = '';
                $queryAuthCode = str_replace('QUERY_AUTH_CODE:', '', $content);
                $ret = WxResourceService::getInstance()->getAuthorizerInfo($queryAuthCode);

                if ($ret) {
                    $accessToken = $ret->authorization_info->authorizer_access_token;
                    apcu_add('at', $accessToken);
                    WxMessageService::getInstance()->sendKfMsg(
                        self::VERIFY_APPID,
                        $xml->FromUserName,
                        $queryAuthCode . '_from_api',
                        $accessToken
                    );
                }
            }
            if ($replyContent) {
                echo $this->replyTextMessageByEncrypt($xml->ToUserName, $xml->FromUserName, $replyContent);
                WxMessageService::getInstance()->sendKfMsg(
                    self::VERIFY_APPID,
                    $xml->FromUserName,
                    $replyContent,
                    apcu_fetch('at')
                );
            } else {
                echo '';
            }
        } else {
            //echo $this->replyTextMessageByEncrypt($xml->ToUserName, $xml->FromUserName, $content);
        }
    }


    private function setVerifyTicket($xml)
    {
        return WxRecordService::getInstance()->updateValue(BusinessConstant::RECORD_SKEY_VERIFY_TICKET, $xml->ComponentVerifyTicket);
    }

    public function authCallBackAction()
    {
        $authCode = $this->getParamValue('auth_code');

        if ($appId = WxResourceService::getInstance()->updateAuthorizerInfo($authCode)) {
            static::$_logger->info('auth succ:' . $appId);
            echo 'success';
        } else {
            static::$_logger->info('auth fail');
            echo 'fail';
        }
    }
}